package it.unipd.fbaron.mind_reader_squared.activities;

import it.unipd.fbaron.mind_reader_squared.R;
import it.unipd.fbaron.mind_reader_squared.model.ProfileDAO;
import it.unipd.fbaron.mind_reader_squared.model.ProfileLogic;
import it.unipd.fbaron.mind_reader_squared.model.SymbolLogic;

import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.net.Uri;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.text.format.DateFormat;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.Spinner;
import android.widget.TextView;

public class ManageProfileActivity extends BaseActivity {

	// UI components
	private TextView firstNameText;
	private TextView lastNameText;
	private TextView birthDateText;
	private TextView languageText;
	private Spinner preferredLanguageSpinner;
	private Spinner preferredTtsSpinner;
	private TextView downloadVoiceText;
	private TextView ratingText;
	private CheckBox unlockM2Box;
	private CheckBox unlockM3Box;
	private CheckBox readAllBox;
	private Spinner inputLeftSpinner;
	private Spinner inputRightSpinner;
	private Spinner inputSelectSpinner;

	// Dialogs
	static final int DIALOG_CONFIRM_UNLOCK_M2_ID = 1;
	static final int DIALOG_CONFIRM_UNLOCK_M3_ID = 2;

	// current profile object
	private ProfileDAO profile;

	// spinner variables
	private boolean isLanguageSpinnerSelectable = false;
	private boolean isTtsSpinnerSelectable = false;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.manage_profile_layout);

		// Get all current profile settings
		profile = ProfileLogic.getInstance(dbHelper).loadProfile(profileId);

		// Initialization of UI components
		firstNameText = (TextView) findViewById(R.id.profile_first_name);
		lastNameText = (TextView) findViewById(R.id.profile_last_name);
		birthDateText = (TextView) findViewById(R.id.profile_birthdate);
		languageText = (TextView) findViewById(R.id.profile_language);
		preferredLanguageSpinner = (Spinner) findViewById(R.id.profile_preferred_language_spinner);
		preferredTtsSpinner = (Spinner) findViewById(R.id.profile_preferred_tts_spinner);
		downloadVoiceText = (TextView) findViewById(R.id.profile_download_voice);
		ratingText = (TextView) findViewById(R.id.profile_rating);
		unlockM2Box = (CheckBox) findViewById(R.id.profile_m2);
		unlockM3Box = (CheckBox) findViewById(R.id.profile_m3);
		readAllBox = (CheckBox) findViewById(R.id.profile_read_all);
		inputLeftSpinner = (Spinner) findViewById(R.id.profile_input_left);
		inputRightSpinner = (Spinner) findViewById(R.id.profile_input_right);
		inputSelectSpinner = (Spinner) findViewById(R.id.profile_input_select);

		// Set profile static info
		firstNameText.setText(profile.getFirstName());
		lastNameText.setText(profile.getLastName());
		Date tmp = profile.getBirthDate();
		birthDateText.setText(DateFormat.getDateFormat(this).format(tmp));
		languageText.setText(new Locale(profile.getLanguage())
				.getDisplayLanguage());

		// localeSpinner population
		TypedArray supportedLangs = getResources().obtainTypedArray(
				R.array.supported_lang);
		ArrayAdapter<String> localeStringAdapter = new ArrayAdapter<String>(
				this, android.R.layout.simple_spinner_item);
		final ArrayList<String> localeList = new ArrayList<String>();
		localeStringAdapter.add(new Locale(profile.getPreferredLanguage())
				.getDisplayLanguage());
		localeList.add(profile.getPreferredLanguage());
		for (int i = 0; i < supportedLangs.length(); i++) {
			if (!profile.getPreferredLanguage().equals(
					supportedLangs.getString(i))) {
				String language = supportedLangs.getString(i);
				if (supportedLangs.getString(i).length() > 2) {
					language = language.substring(language.length() - 2);
				}
				Locale currLang = new Locale(language);
				localeStringAdapter.add(currLang.getDisplayLanguage(currLang));
				localeList.add(language);
			}
		}
		preferredLanguageSpinner.setAdapter(localeStringAdapter);
		
		supportedLangs.recycle();

		// rating update
		ratingText.setText(String.valueOf(profile.getRating()));

		// unlock mods update
		if (profile.getOpenM2() > 0) {
			unlockM2Box.setChecked(true);
		}
		if (profile.getOpenM3() > 0) {
			unlockM3Box.setChecked(true);
		}

		// output settings update
		if (profile.getReadAll() > 0) {
			readAllBox.setChecked(true);
		}

		// input settings update
		inputLeftSpinner.setSelection(profile.getInputLeft());
		inputRightSpinner.setSelection(profile.getInputRight());
		inputSelectSpinner.setSelection(profile.getInputSelect());

		// Locale spinner listener
		preferredLanguageSpinner
				.setOnItemSelectedListener(new OnItemSelectedListener() {

					@Override
					public void onItemSelected(AdapterView<?> arg0, View arg1,
							int arg2, long arg3) {
						if (isLanguageSpinnerSelectable) {
							Resources res = getResources();
							Configuration config = new Configuration(res
									.getConfiguration());
							config.locale = new Locale(localeList.get(arg2));
							res.updateConfiguration(config, null);

							// Save in db
							ContentValues cv = new ContentValues();
							cv.put("preferred_language", localeList.get(arg2));
							ProfileLogic.getInstance(dbHelper).updateProfile(
									profileId, cv);

							// Reset defoult texts
							SymbolLogic.getInstance(dbHelper)
									.resetStandardSymbolsTexts(
											ManageProfileActivity.this,
											profileId);

							// Restart activity
							Intent intent = getIntent();
							overridePendingTransition(0, 0);
							finish();
							overridePendingTransition(0, 0);
							startActivity(intent);
						} else {
							isLanguageSpinnerSelectable = true;
						}
					}

					@Override
					public void onNothingSelected(AdapterView<?> arg0) {
					}
				});

		// download voice listener
		downloadVoiceText.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// find the correct package name
				String packageName = "";
				TypedArray svoxLangs = getResources().obtainTypedArray(
						R.array.svox_avaible_languages);
				TypedArray svoxPacks = getResources().obtainTypedArray(
						R.array.svox_avaible_packages);
				for (int i = 0; i < svoxLangs.length(); i++) {
					if (svoxLangs.getString(i).equals(profile.getLanguage())) {
						packageName = svoxPacks.getString(i);
					}
				}
				
				svoxLangs.recycle();
				svoxPacks.recycle();

				if (!packageName.equals("")) {
					String market = "market://details?id=";
					String base = "com.svox.classic.langpack.";
					String referrer = "&referrer=utm_source%3DMindReaderSquared%26utm_medium%3Dandroid%26utm_campaign%3DMindReaderSquared";
					String MARKET_URI = market + base + packageName + referrer;
					Uri marketUri = Uri.parse(MARKET_URI);
					Intent marketIntent;
					marketIntent = new Intent(Intent.ACTION_VIEW, marketUri);
					startActivity(marketIntent);
				}
			}
		});

		// Unlock modes listener
		unlockM2Box.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			@Override
			public void onCheckedChanged(CompoundButton buttonView,
					boolean isChecked) {
				if (isChecked) {
					showDialog(DIALOG_CONFIRM_UNLOCK_M2_ID);
				} else {
					ContentValues cv = new ContentValues();
					cv.put("open_m2", 0);
					ProfileLogic.getInstance(dbHelper).updateProfile(profileId,
							cv);
				}
			}
		});
		unlockM3Box.setOnCheckedChangeListener(new OnCheckedChangeListener() {

			@Override
			public void onCheckedChanged(CompoundButton buttonView,
					boolean isChecked) {
				if (isChecked) {
					showDialog(DIALOG_CONFIRM_UNLOCK_M3_ID);
				} else {
					ContentValues cv = new ContentValues();
					cv.put("open_m3", 0);
					ProfileLogic.getInstance(dbHelper).updateProfile(profileId,
							cv);
				}
			}
		});

		// Read all listener
		readAllBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

			@Override
			public void onCheckedChanged(CompoundButton buttonView,
					boolean isChecked) {
				ContentValues cv = new ContentValues();
				if (isChecked) {
					cv.put("read_all", 1);
				} else {
					cv.put("read_all", 0);
				}
				ProfileLogic.getInstance(dbHelper).updateProfile(profileId, cv);
			}
		});

		// Input methods listener
		inputLeftSpinner
				.setOnItemSelectedListener(new OnItemSelectedListener() {

					@Override
					public void onItemSelected(AdapterView<?> arg0, View arg1,
							int arg2, long arg3) {
						ContentValues cv = new ContentValues();
						cv.put("input_left", arg2);
						ProfileLogic.getInstance(dbHelper).updateProfile(
								profileId, cv);
					}

					@Override
					public void onNothingSelected(AdapterView<?> arg0) {
					}
				});
		inputRightSpinner
				.setOnItemSelectedListener(new OnItemSelectedListener() {

					@Override
					public void onItemSelected(AdapterView<?> arg0, View arg1,
							int arg2, long arg3) {
						ContentValues cv = new ContentValues();
						cv.put("input_right", arg2);
						ProfileLogic.getInstance(dbHelper).updateProfile(
								profileId, cv);
					}

					@Override
					public void onNothingSelected(AdapterView<?> arg0) {
					}
				});
		inputSelectSpinner
				.setOnItemSelectedListener(new OnItemSelectedListener() {

					@Override
					public void onItemSelected(AdapterView<?> arg0, View arg1,
							int arg2, long arg3) {
						ContentValues cv = new ContentValues();
						cv.put("input_select", arg2);
						ProfileLogic.getInstance(dbHelper).updateProfile(
								profileId, cv);
					}

					@Override
					public void onNothingSelected(AdapterView<?> arg0) {
					}
				});
	}

	/*
	 * Tts spinner must be populated in the overridden function onInit because it
	 * need the tts object initialized. For every language available in the
	 * market it verify if it is installed with the function
	 * isLanguageAvailable().
	 */
	@Override
	public void onInit(int status) {
		super.onInit(status);

		// ttsSpinner population
		ArrayAdapter<String> ttsStringAdapter = new ArrayAdapter<String>(this,
				android.R.layout.simple_spinner_item);
		final ArrayList<String> ttsList = new ArrayList<String>();
		Locale[] avaibleLocales = Locale.getAvailableLocales();
		boolean hasPreferredTts = false;
		if (!profile.getPreferredTts().equals("")) {
			hasPreferredTts = true;
			Locale currLang = new Locale(profile.getPreferredTts());
			ttsStringAdapter.add(currLang.getDisplayLanguage(currLang));
			ttsList.add(profile.getPreferredTts());
		} else {
			ttsStringAdapter.add(getString(R.string.profile_no_tts));
			ttsList.add(getString(R.string.profile_no_tts));
		}
		String precLanguage = "";
		for (int i = 0; i < avaibleLocales.length; i++) {
			if (!avaibleLocales[i].getLanguage().equals(
					profile.getPreferredTts())
					&& !avaibleLocales[i].getLanguage().equals(precLanguage)) {
				if ((tts.isLanguageAvailable(avaibleLocales[i]) == TextToSpeech.LANG_AVAILABLE)
						|| (tts.isLanguageAvailable(avaibleLocales[i]) == TextToSpeech.LANG_COUNTRY_AVAILABLE)) {
					ttsStringAdapter.add(avaibleLocales[i]
							.getDisplayLanguage(avaibleLocales[i]));
					ttsList.add(avaibleLocales[i].getLanguage());
				}
				precLanguage = avaibleLocales[i].getLanguage();
			}
		}
		if (hasPreferredTts) {
			ttsStringAdapter.add(getString(R.string.profile_no_tts));
			ttsList.add(getString(R.string.profile_no_tts));
		}
		preferredTtsSpinner.setAdapter(ttsStringAdapter);

		preferredTtsSpinner
				.setOnItemSelectedListener(new OnItemSelectedListener() {

					@Override
					public void onItemSelected(AdapterView<?> arg0, View arg1,
							int arg2, long arg3) {
						if (isTtsSpinnerSelectable) {
							// Save in db
							ContentValues cv = new ContentValues();
							cv.put("preferred_tts", ttsList.get(arg2));
							ProfileLogic.getInstance(dbHelper).updateProfile(
									profileId, cv);

							// Restart activity
							Intent intent = getIntent();
							overridePendingTransition(0, 0);
							finish();
							overridePendingTransition(0, 0);
							startActivity(intent);
						} else {
							isTtsSpinnerSelectable = true;
						}
					}

					@Override
					public void onNothingSelected(AdapterView<?> arg0) {
					}
				});

		// Show download link if necessary
		if (!ttsList.contains(profile.getLanguage())) {
			downloadVoiceText.setVisibility(View.VISIBLE);
		}
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		Dialog dialog;
		AlertDialog.Builder builder;
		builder = new AlertDialog.Builder(this);
		builder.setCancelable(false);
		switch (id) {
		case DIALOG_CONFIRM_UNLOCK_M2_ID:
			builder.setPositiveButton(getString(R.string.yes),
					new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int id) {
							dialog.cancel();
							ContentValues cv = new ContentValues();
							cv.put("open_m2", 1);
							ProfileLogic.getInstance(dbHelper).updateProfile(
									profileId, cv);
						}
					})
					.setNegativeButton(getString(R.string.no),
							new DialogInterface.OnClickListener() {
								@Override
								public void onClick(DialogInterface dialog,
										int which) {
									unlockM2Box.setChecked(false);
									dialog.cancel();
								}
							}).setMessage(R.string.profile_unlock_dialog);
			break;
		case DIALOG_CONFIRM_UNLOCK_M3_ID:
			builder.setPositiveButton(getString(R.string.yes),
					new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int id) {
							dialog.cancel();
							ContentValues cv = new ContentValues();
							cv.put("open_m3", 1);
							ProfileLogic.getInstance(dbHelper).updateProfile(
									profileId, cv);
						}
					})
					.setNegativeButton(getString(R.string.no),
							new DialogInterface.OnClickListener() {
								@Override
								public void onClick(DialogInterface dialog,
										int which) {
									unlockM3Box.setChecked(false);
									dialog.cancel();
								}
							}).setMessage(R.string.profile_unlock_dialog);
			break;
		default:
			dialog = null;
		}
		dialog = builder.create();
		return dialog;
	}

}
